package com.service.business.upload.controller;

import com.service.business.base.service.ConfigService;
import com.service.business.qiniu.service.FileService;
import com.service.business.support.ProjectProperty;
import com.service.business.upload.controller.rep.MultiUploadResult;
import com.service.business.upload.controller.req.UploadFileReq;
import com.service.business.upload.enums.FileEnum;
import com.service.core.exception.CommonException;
import com.service.core.rest.BaseController;
import com.service.core.rest.response.BaseResponse;
import com.service.core.rest.response.OneResponse;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.model.SysConfig;
import com.service.utility.common.RandomUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;


@Slf4j
@RestController
@RequestMapping("file")
public class FileUploadController extends BaseController {

    @Autowired
    private ProjectProperty projectProperty;

    @Autowired
    private ConfigService configService;

    @Autowired
    private FileService fileService;

    /**
     * 实现文件上传
     */
    @RequestMapping("image-upload")
    public OneResponse<String> fileUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            throw new CommonException("没有要上传的文件", "no_file_upload");
        }
        if (!StringUtils.equals(file.getContentType(), FileEnum.image.getType())) {
            throw new CommonException("文件格式错误,请重新上传");
        }

        String fileName = file.getOriginalFilename();
        int size = (int) file.getSize();
        assert fileName != null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        log.info("上传文件名:{},size:{}", fileName, size);
        String newFileName = System.currentTimeMillis() + RandomUtil.randomString(8) + fileType;

//        String path = fileService.uploadImag(file, newFileName);
//        if (StringUtils.isBlank(path)) {
//            throw new CommonException("上传文件失败", "upload_file_exception_fail");
//        }
//        return successQueryOneResponse(path);

        String absoluteFile = projectProperty.getLastDestPath() + File.separator + newFileName;
        String filePath = projectProperty.getDestPath() + absoluteFile;
        File dest = new File(filePath);
        if (!dest.getParentFile().exists()) { //判断文件父目录是否存在
            dest.getParentFile().mkdir();
        }
        dest.setReadable(true, false);
        dest.setExecutable(true, false);
        dest.setWritable(true, false);
        try {
            file.transferTo(dest); //保存文件
            SysConfig config = configService.getConfigByName(ConfigConstants.ADMIN_API_URL);
            return successQueryOneResponse(config.getConfValue() + absoluteFile);
        } catch (IllegalStateException e) {
            log.error("上传文件出错：", e);
            throw new CommonException("文件上传出错", "upload_illegal_state");
        } catch (IOException e) {
            log.error("上传文件出错,IO异常：", e);
            throw new CommonException("文件上传出错", "upload_io_exception");
        }
    }

    @ApiOperation("Base64文件上传")
    @PostMapping("getByCode")
    public BaseResponse getFileByCode(@ApiParam @RequestBody @Validated UploadFileReq uploadFileReq){
        // 生成文件名
        String newFileName = uploadFileReq.getInvitationCode() + "-poster." + uploadFileReq.getImg();
        String absoluteFile = projectProperty.getLastDestPath() + File.separator + newFileName;
        String filePath = projectProperty.getDestPath() + absoluteFile;
        try{
            File tempFile = new File(filePath);
            if(tempFile.exists()){
                String fName = tempFile.getName();
                return successBaseResponse(fName);
            }else {
                return successBaseResponse("");
            }
        }catch (Exception e){
            throw new CommonException("文件不存在");
        }
    }

    /**
     * 实现文件上传，base64
     */
    @ApiOperation("Base64文件上传")
    @PostMapping("base-upload")
    public OneResponse<String> fileUploadBase64(@ApiParam @RequestBody @Validated UploadFileReq uploadFileReq) {

        String dataPrix = "";
        String data = "";
        String [] d = uploadFileReq.getImg().split("base64,");
        if(d.length == 2){
            dataPrix = d[0];
            data = d[1];
        }else{
            throw new CommonException("上传失败，数据不合法");
        }
        String suffix = "";
        if("data:image/jpeg;".equalsIgnoreCase(dataPrix)){
            //编码的jpeg图片数据
            suffix = ".jpg";
        } else if("data:image/x-icon;".equalsIgnoreCase(dataPrix)){
            //编码的icon图片数据
            suffix = ".ico";
        } else if("data:image/gif;".equalsIgnoreCase(dataPrix)){
            //编码的gif图片数据
            suffix = ".gif";
        } else if("data:image/png;".equalsIgnoreCase(dataPrix)){
            //编码的png图片数据
            suffix = ".png";
        }else{
            throw new CommonException("上传图片格式不合法");
        }
        Base64 decoder = new Base64();
//        BASE64Decoder decoder = new BASE64Decoder();
        try {
            byte[] b = decoder.decode(data);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            //生成jpeg图片
            // 生成文件名
            String newFileName = uploadFileReq.getInvitationCode() + "-poster"+suffix;
            // 生成文件路径
            String absoluteFile = projectProperty.getLastDestPath() + File.separator + newFileName;
            String filePath = projectProperty.getDestPath() + absoluteFile;
            OutputStream out = new FileOutputStream(filePath);
            out.write(b);
            out.flush();
            out.close();
            return successQueryOneResponse(newFileName);
        } catch(Exception e) {
            throw new CommonException(e.getMessage());
        }
    }


    /**
     * @param request
     * @return
     */
    @RequestMapping(value = "multifileUpload", method = RequestMethod.POST)
    public List<MultiUploadResult> multifileUpload(HttpServletRequest request) {

        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("fileName");

        if (files.isEmpty()) {
            throw new CommonException("没有要上传的文件", "no_file_upload");
        }
        List<MultiUploadResult> results = new ArrayList<MultiUploadResult>();
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            int size = (int) file.getSize();
            log.info("上传文件名:{},size:{}", fileName, size);

            if (file.isEmpty()) {
                continue;
            } else {
                String filePath = projectProperty.getDestPath() + "/" + fileName;
                File dest = new File(filePath);
                if (!dest.getParentFile().exists()) { //判断文件父目录是否存在
                    dest.getParentFile().mkdir();
                }
                try {
                    file.transferTo(dest);
                    results.add(new MultiUploadResult(fileName, filePath));
                } catch (IllegalStateException e) {
                    log.error("上传文件出错：", e);
                    throw new CommonException("文件上传出错", "upload_illegal_state");
                } catch (IOException e) {
                    log.error("上传文件出错,IO异常：", e);
                    throw new CommonException("文件上传出错", "upload_io_exception");
                }
            }
        }
        return results;
    }
}
